﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Text;
using System.IO;
using System.IO.Compression;

namespace BookWriter
{
    public partial class DocumentEditor : UserControl
    {
        static public void SaveFile(FileDesc fd, RichTextBox richTextBox)
        {
            string filename = fd.FullName;
            if (fd.type < FileType.txz)
                richTextBox.SaveFile(filename, fd.type == FileType.txt ? RichTextBoxStreamType.PlainText : RichTextBoxStreamType.RichText);
            else
            {
                var fs = File.OpenWrite(filename);
                var gs = new DeflateStream(fs, CompressionMode.Compress);
                richTextBox.SaveFile(gs, fd.type == FileType.txt ? RichTextBoxStreamType.PlainText : RichTextBoxStreamType.RichText);
                gs.Close();
                fs.Close();
            }
        }

        static public void LoadFile(FileDesc fd, RichTextBox richTextBox)
        {
            string filename = fd.FullName;
            if (File.Exists(filename))
            {
                if (fd.type < FileType.txz)
                {
                    richTextBox.LoadFile(filename, fd.type == FileType.txt ? RichTextBoxStreamType.PlainText : RichTextBoxStreamType.RichText);
                }
                else
                {
                    var fs = File.OpenRead(filename);
                    var es = new DeflateStream(fs, CompressionMode.Decompress);
                    MemoryStream ms = new MemoryStream();
                    es.CopyTo(ms);
                    ms.Seek(0L, SeekOrigin.Begin);
                    es.Close();
                    fs.Close();
                    richTextBox.LoadFile(ms, fd.type == FileType.txt ? RichTextBoxStreamType.PlainText : RichTextBoxStreamType.RichText);
                    ms.Close();
                }
            }
        }

        public delegate void OnEvent(DocumentEditor sender);
        public delegate void OnEventType(DocumentEditor sender,FileType old_type);

        public event OnEvent onContentChange;
        public event OnEvent onContentSaved;
        public event OnEventType onContentTypeChanged;

        public float[] fontSizeList = new float[]{5f,6f,8f,9f,10f,11f,12f,14f,16f,18f,24f,32f,48f,64f};

        bool eventOn = true;

        public FileDesc fileDesc;
  
        public DocumentEditor()
        {
            InitializeComponent();
            
        }

        private int findMatchFontSize(float size)
        {
            for (int i = 0; i < fontSizeList.Length; i++)
            {
                if (size <= fontSizeList[i])
                    return i;
            }
            return -1;
        }

        private void setFontSize(float size)
        {
            toolStripComboBox3.Text = size.ToString();
            int idx = findMatchFontSize(size);
            if (idx >= 0)
            {
                if (fontSizeList[idx] == size)
                    toolStripComboBox3.SelectedIndex = idx;
            }
        }

        public void Init(FileDesc fd)
        {
            tsb_text_color.ForeColor = richTextBox.SelectionColor;
            InstalledFontCollection list = new InstalledFontCollection();
            foreach (var fa in list.Families)
            {
                toolStripComboBox1.Items.Add(fa.Name);
            }
            toolStripComboBox1.SelectedItem = richTextBox.Font.Name;
            fileDesc = fd;
            eventOn = false;
            toolStripComboBox2.SelectedItem = fd.type.ToString();

            if (fd.type == FileType.txt || fd.type==FileType.txz)
            {
                foreach (ToolStripItem item in toolStrip1.Items)
                {
                    if ((string)item.Tag == "rtf")
                        item.Visible = false;
                }
            }
            else //rtf
            {
                foreach (ToolStripItem item in toolStrip1.Items)
                {
                    if ((string)item.Tag == "rtf")
                        item.Visible = true;
                }
            }
            for (int i = 0; i < fontSizeList.Length;i++ )
                toolStripComboBox3.Items.Add(fontSizeList[i]);
            Font font = richTextBox.SelectionFont ?? richTextBox.Font;
            float size = font.Size;
            setFontSize(size);
            eventOn = true;
        }

        

        public void SaveFile()
        {
            SaveFile(fileDesc, richTextBox);
        }

        public void LoadFile()
        {
            eventOn = false;
            LoadFile(fileDesc, richTextBox);
            eventOn = true;
        }

        private void richTextBox_TextChanged(object sender, EventArgs e)
        {
            tsl_length.Text = richTextBox.TextLength.ToString();
            if (eventOn && onContentChange != null)
                onContentChange(this);
        }

        private void toolStripButton13_Click(object sender, EventArgs e)
        {
            if (onContentSaved != null)
                onContentSaved(this);
        }

        public bool notEmpty()
        {
            return richTextBox.TextLength > 0;
        }


        private void ChangeType(FileType type)
        {
            if(type!=fileDesc.type)
            {
                if(type==FileType.txt || type==FileType.txz)
                {
                    richTextBox.Text = richTextBox.Text;
                    foreach (ToolStripItem item in toolStrip1.Items)
                    {
                        if ((string)item.Tag == "rtf")
                            item.Visible = false;
                    }
                }
                else //rtf
                {
                    foreach (ToolStripItem item in toolStrip1.Items)
                    {
                        if ((string)item.Tag == "rtf")
                            item.Visible = true;
                    }
                }
                FileType old_type = fileDesc.type;
                fileDesc.type = type;
                if (eventOn && onContentTypeChanged != null)
                    onContentTypeChanged(this, old_type);
            }
        }

        private void toolStripComboBox1_Click(object sender, EventArgs e)
        {
            if (eventOn)
            {
                Font font = richTextBox.SelectionFont ?? richTextBox.Font;
                font = new Font(toolStripComboBox1.SelectedItem.ToString(), font.Size, font.Style, font.Unit, font.GdiCharSet, font.GdiVerticalFont);
                richTextBox.SelectionFont = font;
            }
        }

        private void toolStripButton13_Click_1(object sender, EventArgs e)
        {
            richTextBox.Undo();
        }

        private void toolStripButton14_Click(object sender, EventArgs e)
        {
            richTextBox.Redo();
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            Font font = richTextBox.SelectionFont ?? richTextBox.Font;
            float size = font.Size;
            int idx = findMatchFontSize(size);
            if (idx >= 0)
            {
                if (fontSizeList[idx] == size)
                {
                    if (idx + 1 < fontSizeList.Length)
                        idx++;
                    else
                        return;
                }
                font = new Font(font.FontFamily, fontSizeList[idx], font.Style, font.Unit, font.GdiCharSet, font.GdiVerticalFont);
                richTextBox.SelectionFont = font;
                eventOn = false;

                toolStripComboBox3.SelectedIndex = idx;

                eventOn = true;
            }
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            Font font = richTextBox.SelectionFont ?? richTextBox.Font;
            float size = font.Size;
            int idx = findMatchFontSize(size);
            if (idx >0)
            {
                idx--;
                size = fontSizeList[idx];
                font = new Font(font.FontFamily, size, font.Style, font.Unit, font.GdiCharSet, font.GdiVerticalFont);
                richTextBox.SelectionFont = font;
                eventOn = false;

                toolStripComboBox3.SelectedIndex = idx;

                eventOn = true;

            }
        }

        private void toolStripButton7_Click(object sender, EventArgs e)
        {
            richTextBox.SelectionAlignment = HorizontalAlignment.Left;
        }

        private void toolStripButton8_Click(object sender, EventArgs e)
        {
            richTextBox.SelectionAlignment = HorizontalAlignment.Center;
        }

        private void toolStripButton9_Click(object sender, EventArgs e)
        {
            richTextBox.SelectionAlignment = HorizontalAlignment.Right;
        }

        private void toolStripButton10_Click(object sender, EventArgs e)
        {
            richTextBox.SelectionIndent = richTextBox.SelectionIndent - 8;
        }

        private void toolStripButton11_Click(object sender, EventArgs e)
        {
            richTextBox.SelectionIndent = richTextBox.SelectionIndent + 8;
        }

        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            Font font = richTextBox.SelectionFont ?? richTextBox.Font;
            font = new Font(font.FontFamily, font.Size, font.Style ^ FontStyle.Bold, font.Unit, font.GdiCharSet, font.GdiVerticalFont);
            richTextBox.SelectionFont = font;
        }

        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            Font font = richTextBox.SelectionFont ?? richTextBox.Font;
            font = new Font(font.FontFamily, font.Size, font.Style ^ FontStyle.Italic, font.Unit, font.GdiCharSet, font.GdiVerticalFont);
            richTextBox.SelectionFont = font;
        }

        private void toolStripComboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if ((string)toolStripComboBox2.SelectedItem=="txt"&&richTextBox.TextLength > 0 && MessageBox.Show("转换成txt将丢失格式，确定吗？", "确认", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                return;
            if(eventOn)
                ChangeType((FileType)Enum.Parse(typeof(FileType), toolStripComboBox2.SelectedItem.ToString()));
        }


        private void tsb_text_color_Click(object sender, EventArgs e)
        {
            colorDialog1.Color = richTextBox.SelectionColor;
           if(colorDialog1.ShowDialog()==DialogResult.OK)
           {
               richTextBox.SelectionColor = colorDialog1.Color;
               tsb_text_color.ForeColor = colorDialog1.Color;
           }

        }

        private void toolStripButton12_Click(object sender, EventArgs e)
        {
           colorDialog1.Color=richTextBox.SelectionBackColor;
           if (colorDialog1.ShowDialog() == DialogResult.OK)
           {
               richTextBox.SelectionBackColor = colorDialog1.Color;
           }
        }

        private void toolStripComboBox3_TextChanged(object sender, EventArgs e)
        {
            if (eventOn)
            {
                Font font = richTextBox.SelectionFont ?? richTextBox.Font;
                float size = font.Size;
                if (float.TryParse(toolStripComboBox3.Text, out size))
                {
                    font = new Font(font.FontFamily, size, font.Style, font.Unit, font.GdiCharSet, font.GdiVerticalFont);
                    richTextBox.SelectionFont = font;
                }
            }
        }

        private void toolStripComboBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            
            if (eventOn)
            {
                Font font = richTextBox.SelectionFont ?? richTextBox.Font;
                float size = font.Size;
                if (float.TryParse(toolStripComboBox3.SelectedItem.ToString(), out size))
                {
                    font = new Font(font.FontFamily, size, font.Style, font.Unit, font.GdiCharSet, font.GdiVerticalFont);
                    richTextBox.SelectionFont = font;
                }
            }
        }

        private void richTextBox_SelectionChanged(object sender, EventArgs e)
        {
            if (eventOn)
            {
                Font font = richTextBox.SelectionFont;
                if (font != null)
                {
                    eventOn = false;

                    setFontSize(font.Size);
                    toolStripComboBox1.SelectedItem = font.Name;
                    eventOn = true;
                }
                Color color=richTextBox.SelectionColor;
                if(color!=null)
                    tsb_text_color.ForeColor=color;
                int y = richTextBox.GetLineFromCharIndex(richTextBox.SelectionStart)+1;
                int x = richTextBox.SelectionStart - richTextBox.GetFirstCharIndexOfCurrentLine()+1;
                status_location.Text = "行 " + y+ "，列 " + x;
                x=richTextBox.SelectionLength;
                if (x != 0)
                    status_select.Text = "选中" + x;
                else
                    status_select.Text = "";
            }
        }

        
    }
}
